package com.xm.socket;

import com.xm.util.FileUtil;
import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

/**
 * java socket示例
 * 一、简单的客户端-服务器通信，启动startOneServer-startOneClient
 * 二、多客户端连接的服务器，启动startMoreClients-startOneClient，多次客户端消费
 * 三、文件传输，启动startFileServer-startFileClient，上传附件
 * 四、实时聊天系统，启动startChatServer-startChatClient，实时聊天
 */
@Slf4j
public class Server {
    final static List<PrintWriter> clients = new ArrayList<PrintWriter>();

    public static void main(String[] args) throws UnsupportedEncodingException {
        startOneServer(7070);
//        startMoreClients(7071);
//        startFileServer(7072);
//        startChatServer(7073);
    }

    /**
     * 开启一个服务 一个监听
     */
    public static void startOneServer(int port) {
        try (ServerSocket serverSocket = new ServerSocket(port)) {
            log.info("Server[{}] started，waiting for client...", port);

            //等待客户端连接
            Socket socket = serverSocket.accept();
            //设置客户端响应超时时间，毫秒
//            socket.setSoTimeout(5000);

            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            PrintWriter out = new PrintWriter(socket.getOutputStream(), true);

            //读取客户端消息
            String request = in.readLine();
            log.info("Received from client[{}]：{}", port, request);

            //发送响应
            out.println("Hello from server！");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 开启一个服务 多个监听
     */
    public static void startMoreClients(int port) {
        try (ServerSocket serverSocket = new ServerSocket(port)) {
            log.info("Server[{}] started，waiting for clients...", port);

            for (int i = 0; i < 3; i++) {// 最大保持三个连接
                Socket socket = serverSocket.accept();
                new Thread(new ClientListener(socket, i)).start();
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 开启一个文件服务
     */
    public static void startFileServer(int port) {
        try (ServerSocket serverSocket = new ServerSocket(port)) {
            log.info("FileServer[{}] started，waiting for client...", port);

            Socket socket = serverSocket.accept();

            String download = FileUtil.getResourcePath("socket/server.txt");
            assert download != null;
            try (InputStream in = socket.getInputStream();
                 FileOutputStream fileOut = new FileOutputStream(new File(download))) {
                byte[] buffer = new byte[1024];
                int bytesRead;
                while ((bytesRead = in.read(buffer)) != -1) {
                    fileOut.write(buffer, 0, bytesRead);
                }
            }
            log.info("File received and saved！download={}", download);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 开启一个聊天服务
     */
    public static void startChatServer(int port) {
        try (ServerSocket serverSocket = new ServerSocket(port)) {
            log.info("ChatServer[{}] started，waiting for client...", port);

            for (int i = 0; i < 1; i++) {
                log.info("accept[{}] before", i);
                Socket socket = serverSocket.accept();

                //设置客户端响应超时时间，毫秒
                socket.setSoTimeout(5000);

                log.info("accept[{}] after", i);
                PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
                clients.add(out);

                log.info("accept[{}] listen", i);
                new Thread(new ClientListener2(socket, i)).start();
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
